package com.st.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jwt.util.JwtUtils;
import com.jwt.util.RsaUtils;
import com.st.entity.Result;
import com.st.entity.User;
import com.st.entity.UserDto;
import com.st.mapper.IUserMapper;
import com.st.service.IUserService;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
import util.ImageCodeUtil;
import util.SendMessageUtil;
import util.VerifyCodeUtil;

import java.awt.image.BufferedImage;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl extends ServiceImpl<IUserMapper, User> implements IUserService {
    @Autowired
    private IUserMapper iUserMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    //账号登录
    @Override
    public Result login(UserDto userDto) {
        if (userDto == null) {
            return new Result(false,"参数非法");
        }
        int i = Integer.parseInt(userDto.getUserType());
        User myUser = new User();
        myUser.setUserType(i);
        myUser.setAccount(userDto.getAccount());
        QueryWrapper queryWrapper = new QueryWrapper(myUser);
        //管理员用户登录
        if(i==0){
            User user = iUserMapper.selectOne(queryWrapper);
            if (user == null) {
                return new Result(false,"没有此用户");
            }
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            boolean matches = bCryptPasswordEncoder.matches(userDto.getPassword(), user.getPassword());
            if (!matches){
                return new Result(false,"密码错误");
            }
            //颁发令牌
            String token = genJwtToken(user);
            return new Result(true,"登录成功",token);

        } else if(i!=0){//普通用户
            User user = iUserMapper.login(userDto.getAccount());
            if (user == null) {
                return new Result(false,"账号错误");
            }
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            boolean matches = bCryptPasswordEncoder.matches(userDto.getPassword(), user.getPassword());
            if (!matches){
                return new Result(false,"密码错误");
            }
            //颁发令牌
            String token = genJwtToken(user);
            if (token == null) {
                return new Result(false,"token颁发失败");
            }
            User updateUser = new User();
            updateUser.setUserTime(new Date());
            updateUser.setAccount(userDto.getAccount());
            int update = iUserMapper.update(updateUser);
            if (update!=0){
                return new Result(true,"登录成功",token);
            }
        }
        return new Result(false,"没有此用户");
    }
    //手机验证码登录
    @Override
    public Result codeLogin(UserDto userDto) {
        if (userDto == null) {
            return new Result(false,"参数非法");
        }
        User user = iUserMapper.login(userDto.getAccount());
        if (user == null) {
            return new Result(false,"手机号不正确");
        }
        String code_login = stringRedisTemplate.boundValueOps("code_login").get();
        if (code_login == null) {
            return new Result(false,"图形验证码已过期");
        }
        if (!userDto.getPigCode().equalsIgnoreCase(code_login)){
            return new Result(false,"图形验证码错误");
        }
        String key = userDto.getAccount()+"_msg";
        String redisCode = stringRedisTemplate.boundValueOps(key).get();
        if (redisCode == null) {
            return new Result(false,"手机验证码已过期");
        }
        if(!userDto.getMsgCode().equalsIgnoreCase(redisCode)){
            return new Result(false,"手机验证码错误");
        }
        //颁发令牌
        String token = genJwtToken(user);
        if (token == null) {
            return new Result(false,"账号或密码错误");
        }
        User updateUser = new User();
        updateUser.setUserTime(new Date());
        updateUser.setAccount(userDto.getAccount());
        int update = iUserMapper.update(user);
        if (update==0){
            return new Result(false,"登录失败");
        }
        return new Result(true,"登录成功",token);
    }
    //发送短信验证码
    @Override
    public Result sendCode(String phone) {
        User user = iUserMapper.login(phone);
        if (user == null) {
            return new Result(false,"手机号不正确");
        }
        String code = VerifyCodeUtil.generateVerifyCode(4, "abcdqwertyuiop8912345672wqwe");
        boolean b = SendMessageUtil.sendMsg(phone, code);
        if (b){
            String key = phone+"_msg";
            stringRedisTemplate.boundValueOps(key).set(code);
            stringRedisTemplate.expire(key, 30, TimeUnit.MINUTES);
            return new Result(true,"发送成功");
        }
        return new Result(true,"发送失败");
    }
    //发送图形验证码
    @Override
    public Result sendPigCode() {
        BufferedImage image = ImageCodeUtil.getBufferedImage();
        String code = ImageCodeUtil.getCodeNum();
//        String code = VerifyCodeUtil.generateVerifyCode(4, "abcdqwertyuiop8912345672wqwe");
        stringRedisTemplate.boundValueOps("code_login").set(code);
        stringRedisTemplate.expire("code_login",5,TimeUnit.MINUTES);
        return new Result(true,"验证码生成",image);
    }
    //验证图形验证码
    @Override
    public Result verifyCode(String code) {
        String code1 = stringRedisTemplate.boundValueOps("code_login").get();
        if (code1 == null) {
            return new Result(false,"验证码过期");
        }
        if (!code.equalsIgnoreCase(code1)){
            return new Result(false,"验证码错误");
        }
        return new Result(true,"验证码正确");
    }
    //校验token
    @Override
    public Result check(String token) {
        if (StringUtils.isEmpty(token)){
            return new Result(false,"token为空");
        }else {
            PublicKey publicKey =null;
            try {
                publicKey = RsaUtils.getPublicKey(ResourceUtils.getFile("classpath:ras_public").getPath());
            } catch (Exception e) {
                e.printStackTrace();
            }

        try {
            User infoFromToken = (User) JwtUtils.getInfoFromToken(token, publicKey, User.class);
            return  new Result(true,"token校验成功");
        } catch (MalformedJwtException e) {
            e.printStackTrace();
            return  new Result(false,"token解析异常");
        }catch (ExpiredJwtException exception){
            exception.printStackTrace();
            return  new Result(false,"token过期");
        }
    }

    }


    //根据私钥生成token
    private String genJwtToken(Object user){
        try {
            //从类路径中获取私钥
            String privateKeyPath = ResourceUtils.getFile("classpath:ras_private").getPath();
            PrivateKey privateKey = RsaUtils.getPrivateKey(privateKeyPath);

            String jwtToken = JwtUtils.generateTokenExpireInMinutes(user, privateKey, 120);
            System.out.println(jwtToken);
            return jwtToken;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }
}
